import threading

import openpyxl
import requests
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QCursor, QPixmap, QIcon, QImage
from PyQt5.QtWidgets import QAbstractItemView, QHeaderView, QMessageBox, QAction, QMenu, QTableView, QFileDialog, QLabel

import config_util
from entity.journal import Journal
from global_config import TYPE_LINK
from gui.main.mainwindow import Ui_MainWindow
from main import type_get, get_article, get_article_detail
from my_util import login


class MainWindowEvent(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MainWindowEvent, self).__init__()
        self.type_link_list = None
        self.setupUi(self)
        self.conf = config_util.get()
        self.init_data()

    def init_data(self):
        self.show_log("启动成功...")
        self.setWindowTitle("SCI期刊爬虫")
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)  # 设置只能选中整行
        self.tableView.setSelectionMode(QAbstractItemView.SingleSelection)  # 只允许选中一行
        self.tableView.setEditTriggers(QTableView.NoEditTriggers)  # 不可以编辑
        # 列宽自适应
        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableView.horizontalHeader().resizeSections(QHeaderView.ResizeToContents)
        self.lineEdit_email.setText(self.conf['email'])
        self.lineEdit_password.setText(self.conf['password'])
        self.set_tables()
        self.bind_event()

    def bind_event(self):
        self.pushButton_login.clicked.connect(self.login)
        # 右键菜单
        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.contextMenuPolicy()
        self.listWidget.customContextMenuRequested[QtCore.QPoint].connect(self.right_context_menu)
        self.pushButton_delete.clicked.connect(self.delete)
        self.pushButton_deleteAll.clicked.connect(self.deleteAll)
        self.pushButton_refresh.clicked.connect(self.refresh)
        self.pushButton_export.clicked.connect(self.export)
        self.pushButton_distinct.clicked.connect(self.distinct)

    def distinct(self):
        query = Journal.select().group_by(Journal.issn).distinct()
        ids = []
        querys = iter(query)
        for i in querys:
            ids.append(i.id)
        Journal.delete().where(Journal.id.not_in(ids)).execute()
        self.set_tables()

    def export(self):
        self.show_log("正在导出...")
        # 写 Excel
        book = openpyxl.Workbook()
        sheet = book.active
        # fff = [filed[0] for filed in cur.description]  # 获取表头信息
        sheet.append(self.header)
        for i in Journal.select():
            sheet.append([str(i.id), i.name, i.keyword, str(i.score), i.issn, i.e_issn, i.new_if, i.introduce, i.link,
                          i.direction])
        filepath = QFileDialog.getSaveFileName(self, '文件保存', '/SCI期刊爬取结果', 'xlsx(*.xlsx)')  # 选择路径
        re = book.save("%s" % filepath[0])
        if re is None:
            QMessageBox.information(self, "导出成功", "文件已导出到" + filepath[0])
            self.show_log("导出成功：文件已导出到" + filepath[0])

    def refresh(self):
        self.set_tables()

    def deleteAll(self):
        if Journal.delete().execute() > 0:
            self.show_log("数据库全部删除完毕")
            self.set_tables()

    def delete(self):
        index = self.model.itemData(self.model.index(self.tableView.currentIndex().row(), 0)).get(0)
        if index is not None:
            if Journal.delete_by_id(index) > 0:
                self.show_log("删除成功")
                self.set_tables()
        else:
            self.show_log("请先选择要删除的行")

    def right_context_menu(self, point):
        def start():
            index = self.listWidget.currentIndex().row()
            it = self.type_link_list[index]
            page = int(it['number'].replace("(", "").replace(")", "")) // 10 + 1
            t = threading.Thread(target=get_article, args=(self, TYPE_LINK + it['link'], page))
            t.start()

        menu = QMenu()
        menu.addAction(QAction(u"爬取", self, triggered=start))
        menu.exec_(QCursor.pos())

    def login(self):
        email = self.lineEdit_email.text()
        password = self.lineEdit_password.text()
        login_res = login(email, password)
        if login_res is False:
            QMessageBox.warning(self, "登录失败", "用户名或者密码错误！")
            return
        config_util.update('email', email)
        config_util.update('password', password)
        self.show_log("登录成功!请右键期刊类型点击爬取")
        self.type_link_list = type_get(self, TYPE_LINK)
        self.listWidget.clear()  # 清空列表
        for i in self.type_link_list:
            self.listWidget.addItem(i['title'])

    def show_log(self, text: str):
        self.textBrowser.append(text)

    def set_tables(self):
        count = Journal.select().count()
        self.label_showCount.setText("共：" + str(count) + "条")
        self.header = ['编号', '名称', '关键字', '评分', 'ISSN', 'E-ISSN', "最新IF", '期刊简介', '来源链接', '研究方向']
        colunm = len(self.header)
        count = Journal.select().count()
        self.model = QStandardItemModel(0, colunm)
        # 设置水平方向两个头标签文本内容
        self.model.setHorizontalHeaderLabels(self.header)
        for it in Journal.select():
            # 显示图片
            # url = "https://media-cdn.oss-cn-hangzhou.aliyuncs.com/statics/images/comment_center/cover/journal/762.jpg"
            # res = requests.get(url)
            # img = QImage.fromData(res.content)
            # item = QStandardItem()
            # item.setIcon(QIcon(QPixmap(img)))
            self.model.appendRow(
                [
                    QStandardItem(str(it.id)),
                    QStandardItem(it.name),
                    QStandardItem(it.keyword),
                    QStandardItem(str(it.score)),
                    QStandardItem(it.issn),
                    QStandardItem(it.e_issn),
                    QStandardItem(it.new_if),
                    QStandardItem(it.introduce),
                    QStandardItem(it.link),
                    QStandardItem(it.direction),
                ])
            self.tableView.setModel(self.model)
